/*!
 * \file pres_parser.cc
 *
 * \brief Implementations to methods declared in pres_parser.h
 *
 * \date Started: 5/17/2010
 * \date Last Modified: 6/10/2010
 * \authors Michelle Strout Alan LaMielle Nicholas Jeanette
 *
 * Copyright (c) 2010, Colorado State University <br>
 * All rights reserved. <br>
 * See ../../COPYING for details. <br>
*/

#include <iegenlib/iegenlib.h>
#include <iostream>
#include <stdio.h>
#include <typeinfo>
#include <stack>

// The yyparse() routine will be defined in the c++ file generated by flex.
// (Put in name of actual file).
extern int yyparse();

namespace iegenlib{ namespace pres_parser{

   /*! a string of input buffer */
   string input_buffer;

   /*! the integer of our input position */
   int input_pos;

   /*! boolean flag set when an error occurs in the parser */
   bool parse_error;

   /// error message for when an error occurs in the parser
   string error_message;
   /*! This is used for the actual parsing of the string we pass in we return
   each char of the string
   @return int the value of each char of our string */
   int string_get_next_char() {
      int retchar = 0;

      //If we are not at the end of the input string buffer
      if (input_pos<input_buffer.length() && !parse_error) {
         //Return the next char in the string
         retchar = input_buffer[input_pos];
         input_pos += 1;
      } else {
         //Otherwise return EOF
         retchar = EOF;
      }

      return retchar;
   }

   /*!PresRelation pointer parse_relation_result. A PresRelation is composed of
   (VarTuple, VarTuple, Conjunction, Symbols)*/
   PresRelation* parse_relation_result;

   /*!PresSet pointer parse_set_result. A PresSet is composed of
   (VarTuple, Conjunction, Symbols)*/
   PresSet* parse_set_result;

   /*!parser_set passes a string representation of a set to the parser and a
   ParseSet gets created.
   @param string set string that is to be parsed
   @return Null pointer if error occurs or a relation is returned
   @return PresSet pointer when parsing is successful
   */
   PresSet* parse_set(string set_string) {
      //reset all fields
      pres_parser::parse_relation_result=NULL;
      pres_parser::parse_set_result=NULL;
      parse_error = false;
      input_buffer.clear();

      //Set the input buffer to the given set string
      input_buffer=set_string;

      //Set the starting position at the first character
      input_pos=0;

      //Run the parser
      yyparse();

      //if the error flag is set return null
      if(parse_error==true){
//         delete parse_set_result;
         throw error_message;
      }

      //if a relation is returned from yyparse return null
      if(parse_set_result == NULL){
//         delete parse_relation_result;
         return NULL;
      }

      return parse_set_result;
   }

   /*! getter for the parse_set_result
   @return PresSet parse_set_result */
   PresSet get_parse_set_result() {
      return (*parse_set_result);
   }

   /*! setter for the parse_set_result
   @param PresSet parse_set_result */
   void set_parse_set_result(PresSet* s) {
      pres_parser::parse_set_result=s;
   }


   /*! passes a relation string into the parser and creates the PresRelation
   @param string relation string that is to be parsed
   @return Null pointer if error occurs or a set is returned
   @return PresRelation pointer when parsing is successful */
   PresRelation* parse_relation(string relation_string) {
      //reset all fields
      pres_parser::parse_relation_result=NULL;
      pres_parser::parse_set_result=NULL;
      parse_error = false;
      input_buffer.clear();

      //Set the input buffer to the given relation string
      input_buffer = relation_string;

      //Set the starting position at the first character
      input_pos=0;

      //Run the parser
      yyparse();

      //if error flag is set then return null
      if(parse_error==true){
         throw error_message;
      }

      //if a set is returned from yyparse return null
      if(parse_relation_result==NULL){
         return NULL;
      }

      return parse_relation_result;
   }

   /*! getter for the parse_relation_result
   @return PresRelation parse_relation_result */
   PresRelation get_parse_relation_result() {
      return (*parse_relation_result);
   }

   /*! setter for the parse_relation_result
   @param PresRelation parse_relation_result */
   void set_parse_relation_result(PresRelation* s) {
      pres_parser::parse_relation_result=s;
   }

   /*! sets the parse_error flag to true */
   void set_parse_error(string error){
      parse_error = true;
      error_message = error;
   }

   /*! getter for the parse_error flag
   @return bool parse_error */
   bool get_parse_error(){
      return parse_error;
   }

   /*! clearAll frees (if needed) and resets the parse_relation_result and the
   parse_set_result so no data is left in those variables*/
   void clearAll(){
      if(parse_relation_result!=NULL){
         delete parse_relation_result;
      }
      if(parse_set_result!=NULL){
         delete parse_set_result;
      }
      pres_parser::parse_relation_result=NULL;
      pres_parser::parse_set_result=NULL;
   }

}}//end namespace iegenlib::pres_parser
